package com.moon.service.juc;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author thy
 * @description：todo
 * @date 2024/7/18 16:51
 */
@Slf4j
public class SingleBlockPoolExecutor {
    /**
     * 自定义配置线程池（线程池核心线程数、最大线程数、存活时间设置、采用的队列类型、线程工厂类、线程池拒绝处理类）
     */
    private final ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 10, 1, TimeUnit.SECONDS,
            new ArrayBlockingQueue<Runnable>(100), new BlockThreadFactory(), new BlockRejectedExecutionHandler());

    /**
     * 自定义线程工厂，重写newThread方法，即可自定义创建线程
     */
    public static class BlockThreadFactory implements ThreadFactory {

        private AtomicInteger count = new AtomicInteger(0);

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            int num = count.addAndGet(1);
            String threadName = SingleBlockPoolExecutor.class.getSimpleName() + "-" + num;
            t.setName(threadName);
            log.info("创建了第{}个线程,并设置了名字",num);
            return t;
        }
    }

    /**
     * 自定义线程池拒绝机制处理类
     */
    public static class BlockRejectedExecutionHandler implements RejectedExecutionHandler {

        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            try {
                //被拒线程再次返回阻塞队列进行等待处理
                log.info("出现了被拒绝的线程。。。。。。。。。。。");
                //此处最好增加限流机制：休眠一段时间后重试
                Thread.sleep(1000); // 等待1秒后重试
                executor.getQueue().put(r);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    /**
     * 线程池销毁方法
     */
    public void destroy() {
        if (pool != null) {
            //线程池销毁
            pool.shutdownNow();
        }
    }


    /**
     * get方法
     * @return
     */
    public ThreadPoolExecutor getPool() {
        return pool;
    }

    /**
     *  私有化构造方法-单例
     */
    private SingleBlockPoolExecutor() {
    }

    /**
     * 在静态内部类中持有单例类的实例，并且可直接被初始化
     */
    private static class Holder {
        private static SingleBlockPoolExecutor singleBlockPoolExecutor = new SingleBlockPoolExecutor();
    }


    /**
     * 获取当前类的单例实例
     * @return
     */
    public static SingleBlockPoolExecutor getSingleBlockPoolExecutor() {
        return Holder.singleBlockPoolExecutor;
    }

}
